home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / cdiff.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  6KB  |  291 lines

  1. /* cdiff - context diff            Author: Larry Wall */
  2.  
  3. /* Cdiff - turns a regular diff into a new-style context diff
  4.  *
  5.  * Usage: cdiff file1 file2
  6.  */
  7.  
  8. #define PATCHLEVEL 2
  9.  
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <ctype.h>
  13. #include <stdio.h>
  14.  
  15. char buff[512];
  16.  
  17. FILE *inputfp, *oldfp, *newfp;
  18. char *ctime();
  19.  
  20. int oldmin, oldmax, newmin, newmax;
  21. int oldbeg, oldend, newbeg, newend;
  22. int preoldmax, prenewmax;
  23. int preoldbeg, preoldend, prenewbeg, prenewend;
  24. int oldwanted, newwanted;
  25.  
  26. char *oldhunk, *newhunk;
  27. unsigned oldsize, oldalloc, newsize, newalloc;
  28.  
  29. void dumphunk();
  30. char *getold();
  31. char *getnew();
  32. char *malloc();
  33. char *realloc();
  34. char *fgets();
  35. FILE *popen();
  36.  
  37. #define Nullfp (FILE*)0
  38. #define Nullch (char*)0
  39.  
  40. main(argc, argv)
  41. int argc;
  42. char **argv;
  43. {
  44.   char *old, *new;
  45.   int context = 3;
  46.   struct stat statbuf;
  47.   register char *s;
  48.   char op;
  49.   char *newmark, *oldmark;
  50.   int len;
  51.   char *line;
  52.   int i;
  53.  
  54.   oldalloc = 512;
  55.   oldhunk = malloc(oldalloc);
  56.   newalloc = 512;
  57.   newhunk = malloc(newalloc);
  58.  
  59.   for (argc--, argv++; argc; argc--, argv++) {
  60.     if (argv[0][0] != '-') break;
  61.  
  62.     if (argv[0][1] == 'c') context = atoi(argv[0] + 2);
  63.   }
  64.  
  65.   if (argc != 2) {
  66.     fprintf(stderr, "Usage: cdiff old new\n");
  67.     exit(1);
  68.   }
  69.   old = argv[0];
  70.   new = argv[1];
  71.  
  72.   sprintf(buff, "diff %s %s", old, new);
  73.   inputfp = popen(buff, "r");
  74.   if (!inputfp) {
  75.     fprintf(stderr, "Can't execute diff %s %s\n", old, new);
  76.     exit(1);
  77.   }
  78.   oldfp = fopen(old, "r");
  79.   if (!oldfp) {
  80.     fprintf(stderr, "Can't open %s\n", old);
  81.     exit(1);
  82.   }
  83.   newfp = fopen(new, "r");
  84.   if (!newfp) {
  85.     fprintf(stderr, "Can't open %s\n", new);
  86.     exit(1);
  87.   }
  88.   fstat(fileno(oldfp), &statbuf);
  89.   printf("*** %s\t%s", old, ctime(&statbuf.st_mtime));
  90.   fstat(fileno(newfp), &statbuf);
  91.   printf("--- %s\t%s", new, ctime(&statbuf.st_mtime));
  92.  
  93.   preoldend = -1000;
  94.  
  95.   while (fgets(buff, sizeof buff, inputfp) != Nullch) {
  96.     if (isdigit(*buff)) {
  97.         oldmin = atoi(buff);
  98.         for (s = buff; isdigit(*s); s++);
  99.         if (*s == ',') {
  100.             s++;
  101.             oldmax = atoi(s);
  102.             for (; isdigit(*s); s++);
  103.         } else {
  104.             oldmax = oldmin;
  105.         }
  106.         if (*s != 'a' && *s != 'd' && *s != 'c') {
  107.             fprintf(stderr, "Unparseable input: %s", s);
  108.             exit(1);
  109.         }
  110.         op = *s;
  111.         s++;
  112.         newmin = atoi(s);
  113.         for (; isdigit(*s); s++);
  114.         if (*s == ',') {
  115.             s++;
  116.             newmax = atoi(s);
  117.             for (; isdigit(*s); s++);
  118.         } else {
  119.             newmax = newmin;
  120.         }
  121.         if (*s != '\n' && *s != ' ') {
  122.             fprintf(stderr, "Unparseable input: %s", s);
  123.             exit(1);
  124.         }
  125.         newmark = oldmark = "! ";
  126.         if (op == 'a') {
  127.             oldmin++;
  128.             newmark = "+ ";
  129.         }
  130.         if (op == 'd') {
  131.             newmin++;
  132.             oldmark = "- ";
  133.         }
  134.         oldbeg = oldmin - context;
  135.         oldend = oldmax + context;
  136.         if (oldbeg < 1) oldbeg = 1;
  137.         newbeg = newmin - context;
  138.         newend = newmax + context;
  139.         if (newbeg < 1) newbeg = 1;
  140.  
  141.         if (preoldend < oldbeg - 1) {
  142.             if (preoldend >= 0) {
  143.                 dumphunk();
  144.             }
  145.             preoldbeg = oldbeg;
  146.             prenewbeg = newbeg;
  147.             oldwanted = newwanted = 0;
  148.             oldsize = newsize = 0;
  149.         } else {    /* we want to append to previous hunk */
  150.             oldbeg = preoldmax + 1;
  151.             newbeg = prenewmax + 1;
  152.         }
  153.  
  154.         for (i = oldbeg; i <= oldmax; i++) {
  155.             line = getold(i);
  156.             if (!*line) {
  157.                 oldend = oldmax = i - 1;
  158.                 break;
  159.             }
  160.             len = strlen(line) + 2;
  161.             if (oldsize + len + 1 >= oldalloc) {
  162.                 oldalloc *= 2;
  163.                 oldhunk = realloc(oldhunk, oldalloc);
  164.             }
  165.             if (i >= oldmin) {
  166.                 strcpy(oldhunk + oldsize, oldmark);
  167.                 oldwanted++;
  168.             } else {
  169.                 strcpy(oldhunk + oldsize, "  ");
  170.             }
  171.             strcpy(oldhunk + oldsize + 2, line);
  172.             oldsize += len;
  173.         }
  174.         preoldmax = oldmax;
  175.         preoldend = oldend;
  176.  
  177.         for (i = newbeg; i <= newmax; i++) {
  178.             line = getnew(i);
  179.             if (!*line) {
  180.                 newend = newmax = i - 1;
  181.                 break;
  182.             }
  183.             len = strlen(line) + 2;
  184.             if (newsize + len + 1 >= newalloc) {
  185.                 newalloc *= 2;
  186.                 newhunk = realloc(newhunk, newalloc);
  187.             }
  188.             if (i >= newmin) {
  189.                 strcpy(newhunk + newsize, newmark);
  190.                 newwanted++;
  191.             } else {
  192.                 strcpy(newhunk + newsize, "  ");
  193.             }
  194.             strcpy(newhunk + newsize + 2, line);
  195.             newsize += len;
  196.         }
  197.         prenewmax = newmax;
  198.         prenewend = newend;
  199.     }
  200.   }
  201.  
  202.   if (preoldend >= 0) {
  203.     dumphunk();
  204.   }
  205. }
  206.  
  207. void dumphunk()
  208. {
  209.   int i;
  210.   char *line;
  211.   int len;
  212.  
  213.   for (i = preoldmax + 1; i <= preoldend; i++) {
  214.     line = getold(i);
  215.     if (!line) {
  216.         preoldend = i - 1;
  217.         break;
  218.     }
  219.     len = strlen(line) + 2;
  220.     if (oldsize + len + 1 >= oldalloc) {
  221.         oldalloc *= 2;
  222.         oldhunk = realloc(oldhunk, oldalloc);
  223.     }
  224.     strcpy(oldhunk + oldsize, "  ");
  225.     strcpy(oldhunk + oldsize + 2, line);
  226.     oldsize += len;
  227.   }
  228.   for (i = prenewmax + 1; i <= prenewend; i++) {
  229.     line = getnew(i);
  230.     if (!line) {
  231.         prenewend = i - 1;
  232.         break;
  233.     }
  234.     len = strlen(line) + 2;
  235.     if (newsize + len + 1 >= newalloc) {
  236.         newalloc *= 2;
  237.         newhunk = realloc(newhunk, newalloc);
  238.     }
  239.     strcpy(newhunk + newsize, "  ");
  240.     strcpy(newhunk + newsize + 2, line);
  241.     newsize += len;
  242.   }
  243.   fputs("***************\n", stdout);
  244.   if (preoldbeg >= preoldend) {
  245.     printf("*** %d ****\n", preoldend);
  246.   } else {
  247.     printf("*** %d,%d ****\n", preoldbeg, preoldend);
  248.   }
  249.   if (oldwanted) {
  250.     fputs(oldhunk, stdout);
  251.   }
  252.   oldsize = 0;
  253.   *oldhunk = '\0';
  254.   if (prenewbeg >= prenewend) {
  255.     printf("--- %d ----\n", prenewend);
  256.   } else {
  257.     printf("--- %d,%d ----\n", prenewbeg, prenewend);
  258.   }
  259.   if (newwanted) {
  260.     fputs(newhunk, stdout);
  261.   }
  262.   newsize = 0;
  263.   *newhunk = '\0';
  264. }
  265.  
  266. char *
  267.  getold(targ)
  268. int targ;
  269. {
  270.   static int oldline = 0;
  271.  
  272.   while (fgets(buff, sizeof buff, oldfp) != Nullch) {
  273.     oldline++;
  274.     if (oldline == targ) return buff;
  275.   }
  276.   return Nullch;
  277. }
  278.  
  279. char *
  280.  getnew(targ)
  281. int targ;
  282. {
  283.   static int newline = 0;
  284.  
  285.   while (fgets(buff, sizeof buff, newfp) != Nullch) {
  286.     newline++;
  287.     if (newline == targ) return buff;
  288.   }
  289.   return Nullch;
  290. }
  291.